package ran.job.handler;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ran.constants.Constants;
import ran.constants.RedisCacheConstants;
import ran.job.domain.entity.Exam;
import ran.job.mapper.ExamMapper;
import ran.redis.service.RedisService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2025-11-12
 * Time: 20:56
 */
@Component
@Slf4j
public class Handler {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ExamMapper examMapper;

    // 查询前一天的竞赛列表,推送给用户
    @XxlJob("examListOrganizeHandler")
    public void examListOrganizeHandler() {
        log.info("调用了 examListOrganizeHandler 方法");
        // 获取未完赛列表
        List<Exam> NoFinishedList;
        NoFinishedList = examMapper.selectList(new LambdaQueryWrapper<Exam>()
                .select(Exam::getExamId,Exam::getTitle,Exam::getStartTime,Exam::getEndTime)
                .eq(Exam::getStatus, Constants.TRUE)
                .gt(Exam::getEndTime, LocalDateTime.now()) // 未完赛, 结束时间大于当前时间
                .orderByDesc(Exam::getCreateTime));
        // 刷新未结束的竞赛列表
        refreshCache(NoFinishedList, RedisCacheConstants.EXAM_UNFINISHED_LIST);

        // 获取历史竞赛列表
        List<Exam> historyList;
        historyList = examMapper.selectList(new LambdaQueryWrapper<Exam>()
                .select(Exam::getExamId,Exam::getTitle,Exam::getStartTime,Exam::getEndTime)
                .eq(Exam::getStatus, Constants.TRUE)
                .le(Exam::getEndTime, LocalDateTime.now()) // 历史竞赛, 结束时间小于等于当前时间
                .orderByDesc(Exam::getCreateTime));
        // 刷新历史竞赛列表
        refreshCache(historyList, RedisCacheConstants.EXAM_HISTORY_LIST);
    }

    private void refreshCache(List<Exam> list, String listKey) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        // 竞赛详细信息的map
        Map<String, Exam> examMap = new HashMap<>();
        // 未完赛信息的 examId集合
        List<Long> examIdList = new ArrayList<>();
        for (Exam exam : list) {
            examMap.put(getDetailKey(exam.getExamId()),exam);
            examIdList.add(exam.getExamId());
        }
        // 批量添加/更新Redis中竞赛详细信息, 这里因为我们是用的是String类型, key一样时自动覆盖, 所以不用提前删除
        redisService.multiSet(examMap);
        // 先清楚旧的数据, 再更新新的数据, 这里存的是 竞赛id
        redisService.deleteObject(listKey);
        redisService.rightPushAll(listKey,examIdList);// 尾差, 因为我们查出来的数据是排好序的
    }

    private String getDetailKey(Long examId) {
        return RedisCacheConstants.EXAM_DETAIL + examId;
    }
}
